use std::sync::Arc;

use egui::{Id, Vec2};
use thunderdome::Index;
use uuid::Uuid;
use QcCore::scene_system::scene::Scene;
use QcScript::core::JsComponent;
use QcUI::{
    component::{Button, ButtonMessage, Canvas},
    core::uiBind::{JsUiBind, JsUiBindData, UiBind},
    message::UiMessageType,
};

use crate::{
    core::{context::Context, message::EditorMessage},
    inspector::{ComponentState, InspectorContext, InspectorTrait},
};

#[derive(Debug)]
pub struct ButtonState {
    context: Arc<Context>,

    click_event: Option<JsUiBindData>,
    ui_bind_list: Option<Vec<JsUiBindData>>,
}

impl ButtonState {
    pub fn new(context: Arc<Context>) -> Self {
        Self {
            context,
            click_event: None,
            ui_bind_list: None,
        }
    }

    pub fn get_ui_bind_list(&self, scene: &mut Scene) -> Vec<JsUiBindData> {
        let mut objs = vec![];
        for (obj_id, obj) in scene.iter() {
            if let Some((comp_id, comp)) = obj.getComponentAndId::<JsComponent>() {
                objs.push(JsUiBindData::new(
                    obj_id,
                    &obj.name,
                    comp_id,
                    comp.getName(),
                ));
            }
        }
        println!("{:?}", objs);
        objs
    }

    pub fn get_click_event(
        &self,
        scene: &mut Scene,
        canvas: &mut Canvas,
        uuid: Uuid,
    ) -> Option<JsUiBindData> {
        if let Some(index) = scene.get_main_canvas() {
            if let Some(canvas) = scene[index].getComponent::<Canvas>() {
                if let Some(bind) = canvas.getUiBind(uuid) {
                    let bind = bind
                        .iter()
                        .filter(|b| {
                            b.is_js_bind()
                                && b.get_msg_type()
                                    .eq(&UiMessageType::ButtonMessage(ButtonMessage::Clicked))
                        })
                        .map(|b| {
                            let UiBind::JsBind(b) = b else { panic!() };
                            let obj = &scene[b.objId];
                            let obj_name = &obj.name;
                            let comp_name = obj[b.compId].getName();

                            JsUiBindData::new(b.objId, obj_name, b.compId, comp_name)
                                .with_func_name(&b.funcName)
                        })
                        .collect::<Vec<JsUiBindData>>();

                    return bind.first().cloned();
                }
            }
        }

        Some(JsUiBindData::default())
    }
}

impl InspectorTrait for Button {
    fn inspector(&mut self, ctx: &mut InspectorContext, state: &mut ComponentState) {
        let ComponentState::Button(state) = state else {
            panic!("获取不到 ButtonState")
        };

        let canvas = unsafe { &mut *ctx.canvas_ptr };
        let scene = unsafe { &mut *ctx.scene_ptr };

        if state.click_event.is_none() {
            state.click_event = state.get_click_event(scene, canvas, self.uuid);

            state.ui_bind_list = Some(state.get_ui_bind_list(scene));
        }

        let click_event = state.click_event.as_mut().unwrap();
        let ui_bind_list = state.ui_bind_list.as_mut().unwrap();

        egui::CollapsingHeader::new("Button")
            .default_open(true)
            .show(ctx.ui, |ui| {
                ui.group(|ui| {
                    ui.set_min_width(ui.available_width() - 5.);
                    egui::Grid::new("Button")
                        .num_columns(2)
                        .min_col_width(70.)
                        .spacing(Vec2::new(10., 10.))
                        .show(ui, |ui| {
                            ui.label("文本");
                            ui.text_edit_singleline(&mut self.text);
                            ui.end_row();

                            ui.label("悬浮颜色");
                            ui.color_edit_button_srgba(&mut self.hoverColor);
                            ui.end_row();

                            ui.label("点击颜色");
                            ui.color_edit_button_srgba(&mut self.clickColor);
                            ui.end_row();

                            ui.label("点击事件");

                            // if ui.button("click").clicked() {
                            //     let vec = state.get_click_event(scene, canvas, self.uuid);
                            //     println!("{:?}", vec);
                            // }
                            egui::Grid::new("Button")
                                .num_columns(2)
                                .min_col_width(70.)
                                .spacing(Vec2::new(10., 10.))
                                .show(ui, |ui| {
                                    ui.label("游戏对象");
                                    egui::ComboBox::from_id_source(Id::new("GameObject Id"))
                                        .selected_text(format!("{:?}", click_event.get_obj_name()))
                                        .show_ui(ui, |ui| {
                                            for obj in ui_bind_list.iter() {
                                                ui.selectable_value(
                                                    &mut click_event.obj,
                                                    (
                                                        obj.get_obj_id(),
                                                        obj.get_obj_name().to_string(),
                                                    ),
                                                    obj.get_obj_name(),
                                                );
                                            }
                                        });
                                    ui.end_row();

                                    ui.label("组件");
                                    egui::ComboBox::from_id_source(Id::new("Component Id"))
                                        .selected_text(format!("{:?}", click_event.get_comp_name()))
                                        .show_ui(ui, |ui| {
                                            for obj in ui_bind_list.iter() {
                                                ui.selectable_value(
                                                    &mut click_event.comp,
                                                    (
                                                        obj.get_comp_id(),
                                                        obj.get_comp_name().to_string(),
                                                    ),
                                                    obj.get_comp_name(),
                                                );
                                            }
                                        });

                                    ui.end_row();

                                    ui.label("方法名");
                                    ui.text_edit_singleline(click_event.get_func_name_mut());
                                    ui.end_row();

                                    if ui.button("保存").clicked() {
                                        ctx.sender
                                            .send(EditorMessage::AddUiBind(
                                                self.uuid,
                                                JsUiBind::new(
                                                    click_event.get_obj_id(),
                                                    click_event.get_comp_id(),
                                                    click_event.get_func_name(),
                                                    UiMessageType::ButtonMessage(
                                                        ButtonMessage::Clicked,
                                                    ),
                                                ),
                                            ))
                                            .unwrap();
                                    }
                                    ui.button("刷新");
                                    ui.end_row();
                                });

                            ui.end_row();
                        })
                });
            });
    }
}
